diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-02 00:45:49 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-02 00:45:49 +0000 |
| commit | 2acf5f8966a40c1c9a97680c8dc263ee3f1ad3d1 (patch) | |
| tree | f406b5c86f563347c7fd088a85fd1a82284dc5ff /app/[lng]/engineering/(engineering)/report | |
| parent | 6a9ca20deddcdcbe8495cf5a73ec7ea5f53f9b55 (diff) | |
(대표님/최겸) 20250702 변경사항 업데이트
Diffstat (limited to 'app/[lng]/engineering/(engineering)/report')
| -rw-r--r-- | app/[lng]/engineering/(engineering)/report/page.tsx | 154 |
1 files changed, 118 insertions, 36 deletions
diff --git a/app/[lng]/engineering/(engineering)/report/page.tsx b/app/[lng]/engineering/(engineering)/report/page.tsx index 3efaa7c3..eb932e0f 100644 --- a/app/[lng]/engineering/(engineering)/report/page.tsx +++ b/app/[lng]/engineering/(engineering)/report/page.tsx @@ -1,47 +1,129 @@ -import * as React from "react" -import { Skeleton } from "@/components/ui/skeleton" -import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton" -import { Shell } from "@/components/shell" +// app/procurement/dashboard/page.tsx +import * as React from "react"; +import { Skeleton } from "@/components/ui/skeleton"; +import { Shell } from "@/components/shell"; +import { ErrorBoundary } from "@/components/error-boundary"; +import { getDashboardData } from "@/lib/dashboard/service"; +import { DashboardClient } from "@/lib/dashboard/dashboard-client"; +// 대시보드 데이터 로딩 컴포넌트 +async function DashboardContent() { + try { + const data = await getDashboardData("engineering"); + + const handleRefresh = async () => { + "use server"; + return await getDashboardData("engineering"); + }; -export default async function IndexPage() { - + return ( + <DashboardClient + initialData={data} + onRefresh={handleRefresh} + /> + ); + } catch (error) { + console.error("Dashboard data loading error:", error); + throw error; + } +} +// 대시보드 로딩 스켈레톤 +function DashboardSkeleton() { return ( - <Shell className="gap-2"> + <div className="space-y-6"> + {/* 헤더 스켈레톤 */} <div className="flex items-center justify-between"> - <div> - <h2 className="text-2xl font-bold tracking-tight"> - Dashboard - </h2> - <p className="text-muted-foreground"> - 각종 지표 등을 대시보드로 표현하거나 리포트를 출력할 수 있습니다. - </p> + <div className="space-y-2"> + <Skeleton className="h-8 w-48" /> + <Skeleton className="h-4 w-72" /> + </div> + <Skeleton className="h-10 w-24" /> + </div> + + {/* 요약 카드 스켈레톤 */} + <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4"> + {[...Array(4)].map((_, i) => ( + <div key={i} className="space-y-3 p-6 border rounded-lg"> + <div className="flex items-center justify-between"> + <Skeleton className="h-4 w-16" /> + <Skeleton className="h-4 w-4" /> + </div> + <Skeleton className="h-8 w-12" /> + <Skeleton className="h-3 w-20" /> + </div> + ))} + </div> + + {/* 차트 스켈레톤 */} + <div className="grid grid-cols-1 lg:grid-cols-2 gap-6"> + {[...Array(2)].map((_, i) => ( + <div key={i} className="space-y-4 p-6 border rounded-lg"> + <div className="space-y-2"> + <Skeleton className="h-6 w-32" /> + <Skeleton className="h-4 w-48" /> + </div> + <Skeleton className="h-[300px] w-full" /> + </div> + ))} + </div> + + {/* 탭 스켈레톤 */} + <div className="space-y-4"> + <Skeleton className="h-10 w-64" /> + <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3"> + {[...Array(6)].map((_, i) => ( + <div key={i} className="space-y-4 p-6 border rounded-lg"> + <Skeleton className="h-6 w-32" /> + <div className="space-y-3"> + <div className="flex justify-between"> + <Skeleton className="h-4 w-16" /> + <Skeleton className="h-4 w-12" /> + </div> + <div className="flex gap-2"> + <Skeleton className="h-6 w-16" /> + <Skeleton className="h-6 w-16" /> + <Skeleton className="h-6 w-16" /> + </div> + <Skeleton className="h-2 w-full" /> + </div> + </div> + ))} </div> </div> + </div> + ); +} - <React.Suspense fallback={<Skeleton className="h-7 w-52" />}> - {/* <DateRangePicker - triggerSize="sm" - triggerClassName="ml-auto w-56 sm:w-60" - align="end" - shallow={false} - /> */} - </React.Suspense> - - <React.Suspense - fallback={ - <DataTableSkeleton - columnCount={6} - searchableColumnCount={1} - filterableColumnCount={2} - cellWidths={["10rem", "40rem", "12rem", "12rem", "8rem", "8rem"]} - shrinkZero - /> - } +// 에러 표시 컴포넌트 +function DashboardError({ error, reset }: { error: Error; reset: () => void }) { + return ( + <div className="flex flex-col items-center justify-center py-12 space-y-4"> + <div className="text-center space-y-2"> + <h3 className="text-lg font-semibold">대시보드를 불러올 수 없습니다</h3> + <p className="text-muted-foreground"> + {error.message || "알 수 없는 오류가 발생했습니다."} + </p> + </div> + <button + onClick={reset} + className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90" > - </React.Suspense> + 다시 시도 + </button> + </div> + ); +} + +export default async function DashboardPage() { + return ( + <Shell className="gap-6"> + <ErrorBoundary fallback={DashboardError}> + <React.Suspense fallback={<DashboardSkeleton />}> + <DashboardContent /> + </React.Suspense> + </ErrorBoundary> </Shell> - ) -}
\ No newline at end of file + ); +} |
